﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
using System.Threading;

namespace LitTools
{
    public class TutorialUI
    {
        public TutorialItem_Common TutorialItem { get; set; }

        private SpriteRenderer blackBg;
        private Canvas canvas;
        private PointerFilterMono pointerFilter;
        private GameObject arrow;
        private GameObject finger;
        private Transform root_top;
        private Transform root_single;

        private TutorialUIItem_TextTip textTip;

        private List<GameObject> arrowList;
        private Dictionary<Transform, TutorialUIParentInfo> moveGoDict;

        private UniTask showTask;
        private CancellationToken cancelToken;

        public void OnInit()
        {
            Reset();
            //ShowTutorial(TutorialItem).WithCancellation(cancelToken);
        }

        public void OnRelease()
        {
            Reset();
            TutorialItem = null;
        }

        /// <summary>
        /// 显示引导
        /// </summary>
        /// <param name="tutorialId"></param>
        public void ShowTutorial(string tutorialId)
        {
            Reset();
            TutorialItem = TutorialManager.Instance.GetTutorialItem(tutorialId) as TutorialItem_Common;
            if (TutorialItem != null)
                ShowTutorial(TutorialItem);
        }

        private async UniTask ShowTutorial(TutorialItem_Common tutorialItem)
        {
            await ShowBlack(tutorialItem);

            AddPointerFilter(tutorialItem);
            ShowArrow(tutorialItem);
            ShowFinger(tutorialItem);
            ShowText(tutorialItem);
            ShowPop(tutorialItem);
            MoveGameObjectTop(tutorialItem);
        }

        private void Reset()
        {
            //showTask?.
            //canvas.sortingLayerName = "UI";
            //隐藏背景
            blackBg.color = new Color(0, 0, 0, 0);
            //隐藏所有箭头
            arrow.SetActive(false);
            arrowList ??= new List<GameObject>();
            for (int i = 0; i < arrowList.Count; i++)
            {
                GameObject.Destroy(arrowList[i]);
            }
            arrowList.Clear();
            //隐藏文本弹窗
            
            //重置点击过滤
            pointerFilter.FilterQueue.Clear();
            pointerFilter.FilterQueue.Add(new NoPassFilter());
            pointerFilter.PointerClickAct += OnPointerFilterClick;
            //移动物体还原
            if (moveGoDict != null)
            {
                //moveGoDict.Keys.ForeachCollection(key =>
                //{
                //    if (key != null
                //        && key.parent != null
                //        && key.parent == root_top)
                //    {
                //        key.SetParent(moveGoDict[key].parent);
                //        key.SetSiblingIndex(moveGoDict[key].siblingIndex);
                //        if (moveGoDict[key].parent.GetComponent<LayoutGroup>() != null)
                //        {
                //            moveGoDict[key].parent.GetComponent<LayoutGroup>().enabled = false;
                //        }
                //    }
                //});

                moveGoDict.Clear();
            }
        }

        private void OnPointerFilterClick()
        {
            if (TutorialItem == null) return;
            //if (TutorialItem.pointerFilterType == PointerFilterType.AnyWhere)
            //{
            //    TutorialManager.Instance.HideTutorial(TutorialItem.id);
            //}
            //else if (TutorialItem.pointerFilterType == PointerFilterType.None)
            //{
            //    if (Input.GetMouseButtonUp(0))
            //        TutorialManager.Instance.HideTutorial(TutorialItem.id);
            //}
        }

        #region 引导表现

        /// <summary>
        /// 显示黑色背景
        /// </summary>
        /// <returns></returns>
        private async UniTask ShowBlack(TutorialItem_Common item)
        {
            if (item.showBlackBg)
                await blackBg.DOColor(new Color(0, 0, 0, .8f), .3f);
        }

        /// <summary>
        /// 显示箭头
        /// </summary>
        /// <param name="infos"></param>
        private void ShowArrow(TutorialItem_Common tutorialItem)
        {
            if (!tutorialItem.showArrow) return;
            for (int i = 0; i < tutorialItem.arrowInfos.Length; i++)
            {
                var temp = GameObject.Instantiate(arrow, root_single);
                temp.transform.position = tutorialItem.arrowInfos[i].position.GetPosition();
                switch (tutorialItem.arrowInfos[i].dir)
                {
                    case TutorialDir.Left:
                        temp.transform.localEulerAngles = new Vector3(0, 0, -90);
                        break;
                    case TutorialDir.Right:
                        temp.transform.localEulerAngles = new Vector3(0, 0, 90);
                        break;
                    case TutorialDir.Up:
                        temp.transform.localRotation = new Quaternion(0, 0, 180, 0);
                        break;
                    case TutorialDir.Down:
                        temp.transform.localRotation = new Quaternion(0, 0, 0, 0);
                        break;
                    default:
                        break;
                }
                temp.SetActive(true);
                arrowList.Add(temp);
            }
        }

        /// <summary>
        /// 显示手指
        /// </summary>
        /// <param name="tutorialItem"></param>
        private void ShowFinger(TutorialItem_Common tutorialItem)
        {
            if (!tutorialItem.showFinger) return;
            var info = tutorialItem.fingerInfo;
            finger.transform.position = info.fingerPos.GetPosition();
            if (info.dir == TutorialDir.Left)
            {
                finger.transform.localScale = Vector3.one;
                finger.transform.localEulerAngles = new Vector3(0, 0, 20);
            }
            else if (info.dir == TutorialDir.Right)
            {
                finger.transform.localScale = new Vector3(-1, 1, 1);
                finger.transform.localEulerAngles = new Vector3(0, 0, -20);
            }
            else if (info.dir == TutorialDir.Up)
            {
                finger.transform.localScale = new Vector3(1, -1, 1);
                finger.transform.localEulerAngles = new Vector3(0, 0, -135);
            }
            finger.SetActive(true);
        }

        /// <summary>
        /// 显示文字
        /// </summary>
        /// <param name="tutorialItem"></param>
        private void ShowText(TutorialItem_Common tutorialItem)
        {
            if (!tutorialItem.showText) return;
            //todo:显示文字
        }

        /// <summary>
        /// 显示气泡
        /// </summary>
        /// <param name="tutorialItem"></param>
        private void ShowPop(TutorialItem_Common tutorialItem)
        {
            if (!tutorialItem.showPop) return;
            //todo:显示气泡
        }

        /// <summary>
        /// 移动物体到顶层
        /// </summary>
        /// <param name="gameObjects"></param>
        private void MoveGameObjectTop(TutorialItem_Common item)
        {
            if (!item.moveGos) return;
            moveGoDict ??= new Dictionary<Transform, TutorialUIParentInfo>();
            for (int i = 0; i < item.moveTopGos.Length; i++)
            {
                var go = item.moveTopGos[i].GetGameObject();
                if (go.transform.parent.GetComponent<LayoutGroup>() != null)
                {
                    go.transform.parent.GetComponent<LayoutGroup>().enabled = false;
                }
                moveGoDict.Add(go.transform, new TutorialUIParentInfo(go.transform.parent, go.transform.GetSiblingIndex()));
                go.transform.SetParent(root_top);
            }
        }

        /// <summary>
        /// 添加点击过滤
        /// </summary>
        /// <param name="item"></param>
        private void AddPointerFilter(TutorialItem_Common item)
        {
            switch (item.pointerFilterInfo.pointerFilterType)
            {
                //todo:PointerFilter
            }
        }

        #endregion
    }

    public struct TutorialUIParentInfo
    {
        public Transform parent;
        public int siblingIndex;

        public TutorialUIParentInfo(Transform parent, int siblingIndex)
        {
            this.parent = parent;
            this.siblingIndex = siblingIndex;
        }
    }
}